package com.chenyun.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ReUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chenyun.boot.datasource.page.PageUtils;
import com.chenyun.common.annotation.Page;
import com.chenyun.common.enums.SmsEnum;
import com.chenyun.common.exceptions.BusinessException;
import com.chenyun.common.vo.PageResult;
import com.chenyun.message.sms.dto.SmsResponseDTO;
import com.chenyun.message.sms.dto.SmsTemplateReqDTO;
import com.chenyun.message.sms.service.client.ISmsClient;
import com.chenyun.message.sms.service.client.impl.SmsClientFactory;
import com.chenyun.satoken.starter.util.SaUtil;
import com.chenyun.system.mapper.SmsTemplateMapper;
import com.chenyun.system.model.SmsChannel;
import com.chenyun.system.model.SmsTemplate;
import com.chenyun.system.param.SmsTemplateQueryPage;
import com.chenyun.system.service.ISmsChannelService;
import com.chenyun.system.service.ISmsTemplateService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.regex.Pattern;

/**
 * SmsTemplateServiceImpl：
 * Description:
 *
 * @author: Lonni
 * @date: 2023/12/11 0011 10:43
 */
@Service
@Slf4j
public class SmsTemplateServiceImpl extends ServiceImpl<SmsTemplateMapper, SmsTemplate> implements ISmsTemplateService {

    /**
     * 匹配 {}变量
     */
    private static final Pattern REG_PARAMS = Pattern.compile("\\{(.*?)}");

    @Autowired
    private ISmsChannelService channelService;


    /**
     * 检验短信模版
     *
     * @param template
     */
    void checkTemplateCode(SmsTemplate template) {

        SmsTemplate templateByCode = this.getTemplateByCode(template.getTemCode());
        if (templateByCode == null) {
            return;
        }
        //不为空,判断是否同一条数据
        if (!template.getId().equals(templateByCode.getId())) {
            throw new BusinessException("已存在此编码的短信模版");
        }
    }

    void syncRemoteSms(SmsTemplate smsTemplate) {
        String remoteId = "", remoteMsg = "";
        try {
            ISmsClient client = SmsClientFactory.me.getClient(SaUtil.getLoginUser().getClientId(), SmsEnum.valueOf(smsTemplate.getChannelCode().toUpperCase()));
            SmsTemplateReqDTO reqDTO = new SmsTemplateReqDTO();
            reqDTO.setTemplateType(SmsTemplateReqDTO.TemplateTypeEnum.values()[smsTemplate.getType()]);
            reqDTO.setTitle(smsTemplate.getTemName());
            reqDTO.setContent(smsTemplate.getContent());
            reqDTO.setTemplateCode(smsTemplate.getTemCode());
            reqDTO.setRemark(smsTemplate.getRemark());
            SmsResponseDTO<SmsResponseDTO.SmsAddTemplateRsp> result = client.syncSmsTemplate(reqDTO);
            if (result.getSuccess()) {
                remoteId = result.getData().getTemplateCode();
                remoteMsg = "同步成功";
            } else {
                remoteId = result.getData().getRequestId();
                remoteMsg = String.format("同步失败,code:{},msg:{},requestId:{}"
                        , result.getData().getCode()
                        , result.getData().getMessage()
                        , result.getData().getRequestId()
                );
            }

        } catch (Exception exception) {
            remoteMsg = "系统执行错误!";
            log.error("同步短信模版到远程失败:{}", exception.getLocalizedMessage());
        }
        smsTemplate.setRemoteTemId(remoteId);
        smsTemplate.setRemoteMsg(remoteMsg);
        this.saveOrUpdate(smsTemplate);
    }


    /**
     * 提取变量
     *
     * @param text
     */
    List<String> getParamFromContent(String text) {
        List<String> allGroup1 = ReUtil.findAllGroup1(REG_PARAMS, text);
        return allGroup1;
    }


    /**
     * 获取短信模版
     *
     * @param code
     * @return
     */
    @Override
    public SmsTemplate getTemplateByCode(String code) {
        return this.getOne(Wrappers.lambdaQuery(SmsTemplate.class).eq(SmsTemplate::getTemCode, code));
    }

    /**
     * 创建模版
     *
     * @param template
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SmsTemplate createTemplate(SmsTemplate template) {
        return this.createTemplateAndSync(template, true);
    }

    /**
     * 添加模版 控制是否同步到短信平台
     *
     * @param template
     * @param isSync   是否同步
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public SmsTemplate createTemplateAndSync(SmsTemplate template, Boolean isSync) {
        this.checkTemplateCode(template);
        SmsChannel channel = channelService.checkChannel(template.getChannelId());
        template.setChannelCode(channel.getChannelCode());
        List<String> paramFromContent = this.getParamFromContent(template.getContent());
        template.setTemParam(paramFromContent);
        this.save(template);
        if (isSync) {
            // 同步到短信平台
            this.syncRemoteSms(template);
        }
        //TODO 更新缓存
        return template;

    }

    @Override
    public Boolean updatetemplate(SmsTemplate template) {
        if (template.getId() == null) {
            throw new BusinessException("模板编号必须传入");
        }

        SmsTemplate template1 = this.getById(template.getId());
        if (template1 == null) {
            throw new BusinessException("未找到此短信模板!");
        }
        //查询远程模板是否已经审核
        ISmsClient client = channelService.getClient(template.getChannelCode());
        SmsResponseDTO<SmsResponseDTO.SmsTemplateStatusRsp> responseDTO = client.querySmsTemplateStatus(template.getRemoteTemId());
        if (responseDTO.getSuccess() && responseDTO.getData().getTemplateStatus() == 1) {
            throw new BusinessException("模板已审核通过,不能修改!");
        }

        BeanUtil.copyProperties(template1, template);
        this.save(template1);
        //TODO 更新缓存
        return true;
    }


    @Override
    public Boolean delTemplate(Long id) {
        boolean b = this.removeById(id);
        return b;
    }

    /**
     * 获取指定短信渠道下模版数量
     *
     * @param id
     * @return
     */
    @Override
    public Long getTemplateCountByChannel(Long id) {
        long count = this.count(Wrappers.lambdaQuery(SmsTemplate.class)
                .eq(SmsTemplate::getChannelId, id)
        );
        return count;
    }


    @Override
    @Page
    public PageResult page(SmsTemplateQueryPage page) {
        List<SmsTemplate> smsTemplates = this.baseMapper.ListPage(page);
        PageResult pageHelperByList = PageUtils.getPageHelperByList(smsTemplates);
        return pageHelperByList;

    }


}



